package com.spzx.user.service.impl;


import cn.hutool.core.util.RandomUtil;
import com.spzx.common.core.constant.Constants;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.core.utils.MobileNumberValidator;
import com.spzx.user.service.SmsService;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.concurrent.TimeUnit;

@Service
public class SmsServiceImpl implements SmsService {
    @Resource
    StringRedisTemplate stringRedisTemplate;
    @Override
    public boolean sendCode(String phone) {
        //业务限制 保证短信接口的安全

        //1、手机号格式校验
        if(!MobileNumberValidator.isValidChineseMobileNumber(phone)){
            throw new RuntimeException("手机号格式错误");
        }
        //2、2分钟内相同手机号不能重复发送短信：防止表单重复提交
        if(stringRedisTemplate.hasKey(Constants.APP_LOGIN_LIMIT_PRIFIX+phone)){
            throw new RuntimeException("请勿频繁获取验证码");
        }
        //3、一天内同一手机号最多获取5次验证码
        String countStr = stringRedisTemplate.opsForValue().get(Constants.APP_LOGIN_COUNT_PRIFIX + phone);
        if(!StringUtils.isEmpty(countStr) && Integer.parseInt(countStr)>=5){
            throw new RuntimeException("验证码发送异常");
        }

        //4、发送短信
        try {
            String code = RandomUtil.randomNumbers(4);

//            //1、创建阿里云短信 的客户端对象：  客户端对象的作用可以访问阿里云短信服务 发送验证码给指定手机号
//            Config config = new Config();
////        config.setEndpoint() 设置阿里云服务器地址
//            config.setEndpoint("dysmsapi.aliyuncs.com");
//            // 如果使用阿里云短信平台 不是云市场的，配置的账号密码就是阿里云的账号密码，不推荐直接使用超级管理员账号
//            // 建议创建一个子账号，为他分配发送短信的权限 （注意：一定要保存子账户的 id和secret）
//            //账号  LTAI5tGxpGqaVFgsE2XnTJ5z
//            config.setAccessKeyId("LTAI5tGxpGqaVFgsE2XnTJ5z");
//            //密码  tl1PyVBxrMN7uiglS5Ia2NhyD7uxvh
//            config.setAccessKeySecret("tl1PyVBxrMN7uiglS5Ia2NhyD7uxvh");
//            Client client = new Client(config);
//            //2、封装请求对象： 发送短信的参数
//            SendSmsRequest sendSmsRequest = new SendSmsRequest()
//                    .setSignName("阿里云短信测试")
//                    .setTemplateCode("SMS_154950909") //短信模板：使用阿里云生成的默认的
//                    .setPhoneNumbers(phone) //必须是阿里云短信平台添加的手机号
//                    .setTemplateParam("{\"code\":\""+ code  +"\"}");//验证码
//            RuntimeOptions runtime = new RuntimeOptions();
//
//            // 复制代码运行请自行打印 API 的返回值
//            //3、使用客户端发送给短信 接受服务端的响应
//            SendSmsResponse smsResponse = client.sendSmsWithOptions(sendSmsRequest, runtime);
//            //解析响应结果  根据code值判断响应是否成功
//            if (!"OK".equals(smsResponse.getBody().getCode())) {
//                throw new RuntimeException(smsResponse.getBody().getMessage());
//            }
            //短信发送成功
            //验证码缓存到redis:  过期时间20分钟
            stringRedisTemplate.opsForValue().set(Constants.APP_LOGIN_CODE_PRIFIX+phone,code,
                    20 , TimeUnit.MINUTES);
            //5、更新手机号获取验证码的频率次数
            //5.1 2分钟内不能重复获取验证码
            stringRedisTemplate.opsForValue().set(Constants.APP_LOGIN_LIMIT_PRIFIX+phone,"1",
                    2 , TimeUnit.MINUTES);
            //5.2 一天内只能发送五次验证码
//            if(stringRedisTemplate.hasKey(RedisPrefixConsts.APP_LOGIN_COUNT_PRIFIX+phone)){
//                //统计次数的key存在  基于之前的值+1
//                stringRedisTemplate.opsForValue().increment((RedisPrefixConsts.APP_LOGIN_COUNT_PRIFIX+phone));
//            }else{
//                //统计次数的key不存在  初始化为1 过期时间为一天
//                stringRedisTemplate.opsForValue().set(RedisPrefixConsts.APP_LOGIN_COUNT_PRIFIX+phone,"1",
//                        1 , TimeUnit.DAYS);
//            }
            if(stringRedisTemplate.opsForValue().increment((Constants.APP_LOGIN_COUNT_PRIFIX+phone))==1L){
                //表示第一次设置count值 ， 需要设置过期时间
                stringRedisTemplate.expire(Constants.APP_LOGIN_COUNT_PRIFIX+phone,1,TimeUnit.DAYS);
            }
            return true;
        } catch (Exception _error) {
            throw new ServiceException(_error.getMessage());
//            TeaException error = new TeaException(_error.getMessage(), _error);
//            // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
//            // 错误 message
//            System.out.println(error.getMessage());
//            // 诊断地址
//            System.out.println(error.getData().get("Recommend"));
//            com.aliyun.teautil.Common.assertAsString(error.message);
        }

    }
}
